/*******************************************************************************
 * Package: com.song.boot.springstudy.netty.simple.handler
 * Type:    NettyServerHandler
 * Date:    2023-06-04 17:48
 *
 * Copyright (c) 2023 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.song.boot.springstudy.netty.chat;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.util.Objects;

/**
 * 需求：1给所有在线用户推送某人上线信息
 *      2客户端 上线、下线、离开通知服务器
 *      3发送消息的时候，自己不接收。推送给其他客户端
 * @author Songxianyang
 * @date 2023-06-04 17:48
 * 自定义一个处理器，需要继承netty规定好的某个HandlerAdapter
 */
public class ChartNettyServerHandler extends SimpleChannelInboundHandler<String> {

    //定义一个channle 组，管理所有的channel
    //GlobalEventExecutor.INSTANCE) 是全局的事件执行器，是一个单例
    private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    // 每当从客户端有消息写入时
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception {
        Channel channel1 = channelHandlerContext.channel();
        for (Channel channel : channelGroup) {
            if (Objects.equals(channel, channel1)) {
                System.out.println("消息已推送给其他客户端"+">>>>>>为："+s);
            } else {
                channel.writeAndFlush(">>>>>"+channel1.remoteAddress()+"发送过来的消息为：：：："+s);
            }
        }
    }
    //表示channel 处于活动状态, 提示 上线
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("---------------"+ctx.channel().remoteAddress()+"--------------------"+"上线！开始聊天吧！");
    }
    //表示channel 处于不活动状态, 提示 xx离线了
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("---------------"+ctx.channel().remoteAddress()+"--------------------"+"离线！");

    }

    /**
     * C、S端一单建立Channel连接，就会触发该方法
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        // 给其他客户端发送某某加入群聊
        Channel channel = ctx.channel();
        channelGroup.writeAndFlush("客户端：》》》》" + channel.remoteAddress() + "已加入群聊系统，注意隐士安全！");
        channelGroup.add(channel);
    }

    /**
     * Channel 下线，通知其他 客户端
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        channelGroup.writeAndFlush("客户端：》》》》" + channel.remoteAddress() + "退出群聊系统");
        System.out.println("channle组个数="+channelGroup.size());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
    }
}
